package async

import (
	"context"
	"encoding/json"
	"enotify/pkg/async/conf"
	"enotify/pkg/async/dao"
	"fmt"
	"github.com/golang/protobuf/ptypes/any"
)

type IAsyncServer interface {
	Push(reqId int64,bizType int32, bizId int64,data *any.Any) (err error)
	Stop()
}
type Async struct {
	c *conf.Config
	s IAsyncServer
	d *dao.Dao
	mid *IDManager
	reqStep int
	bizType []int32
}
func NewAsync (ctx context.Context, conf *conf.Config, srv IAsyncServer,bizType []int32) *Async{
	ac :=&Async{
		c: conf,
		s:srv,
		reqStep: conf.ReqStep,
		d:dao.New(conf),
		bizType: bizType,
	}
	var err error
	ac.mid,err = NewIDManager(bizType,ac.d,ac.reqStep)
	if err != nil {
		panic(err)
	}
	return ac
}

func (sc *Async) getReqId(bizType int32) (id int64, err error) {
	id,err = sc.mid.Get(bizType)
	return
}
func (sc *Async) Push(bizType int32, bizId int64,data *any.Any) (reqId int64,err error) {
	reqId,err = sc.mid.Get(bizType)
	if err != nil {
		return
	}

	areq := AsyncRequest{
		BizType: bizType,
		BizId:   bizId,
		TypeUrl: data.TypeUrl,
		Data:    data.String(),
	}
	key := fmt.Sprintf("r%d",reqId)
	adata,_ := json.Marshal(areq)
	err = sc.d.SaveReq(key,adata)
	if err != nil {
		return
	}
	sc.s.Push(reqId,bizType,bizId,data)
	return
}
func (sc *Async) GetReq(reqId int64) (AsyncRequest,error) {
	areq := AsyncRequest{}
	key := fmt.Sprintf("r%d",reqId)
	jn, err := sc.d.GetReq(key)
	if err != nil {
		return areq,err
	}
	err = json.Unmarshal(jn,&areq)
	if err != nil {
		return areq, err
	}
	return areq,nil
}
func (sc *Async) Stop()  {
	sc.mid.Close()
	sc.d.Close()
}
type AsyncRequest struct {
	BizType int32
	BizId int64
	TypeUrl string
	Data string
}
